/**
 * 消息
 * @constructor
 */
function Message(address, userId) {
    this.instance = false;
    this.connected = false;
    this.address = address;
    this.userId = userId;
    this.autoTimer = undefined;
    this.event = new MessageEvent();
}

Message.prototype = {
    connect: function () {
        if ('WebSocket' in window) {
            console.warn('message', "初始化完成")
        } else {
            console.warn('message', "当前浏览器不支持 H5 WebSocket 请更换浏览器")
            return;
        }

        this.heartbeat();
        this._connect();
    },
    _connect:function (){
        let _this = this;
        try {
            if (this.connected === false) {
                let wsInstance = new WebSocket(this.address);
                wsInstance.onopen = function (ev) {
                    console.info('message', ev)
                    _this.connected = true
                    let service = _this.instance.url.replace('ws://', '').replace('wss://', '');
                    service = (service.substring(service.length - 1) === '/') ? service.substring(0, service.length - 1) : service;
                    console.info('message', '链接成功 => ' + service);
                    _this.sendData(JSON.stringify({
                        a: 'index.login',
                        d: {
                            id: 1,
                            user_id: _this.userId
                        }
                    }));
                }
                wsInstance.onclose = function (ev) {
                    console.warn("message", "onclose", ev)
                    clearInterval(_this.autoTimer);
                    _this.connected = false;
                    console.log("message", '自动重连');
                    setTimeout(function () {
                        if (_this.connected === false) {
                            console.log("message", '重连');
                            _this._connect();
                        }
                    }, 1000);
                }
                wsInstance.onerror = function (ev) {
                    console.warn("message", "onerror", ev)
                }
                wsInstance.onmessage = function (ev) {
                    console.warn(ev)
                    let _data = JSON.parse(ev.data);
                    _this.event.fireEvent(_data);
                }
                this.instance = wsInstance;
            } else {
                this.instance.close(1000, 'Active closure of the user')
            }
        } catch (err) {
            console.warn("message", "创建 WebSocket 对象失败 请检查服务器地址", err);
        }
    },
    closeCode: function (code) {
        let codes = {
            1000: '1000 CLOSE_NORMAL',
            1001: '1001 CLOSE_GOING_AWAY',
            1002: '1002 CLOSE_PROTOCOL_ERROR',
            1003: '1003 CLOSE_UNSUPPORTED',
            1004: '1004 CLOSE_RETAIN',
            1005: '1005 CLOSE_NO_STATUS',
            1006: '1006 CLOSE_ABNORMAL',
            1007: '1007 UNSUPPORTED_DATA',
            1008: '1008 POLICY_VIOLATION',
            1009: '1009 CLOSE_TOO_LARGE',
            1010: '1010 MISSING_EXTENSION',
            1011: '1011 INTERNAL_ERROR',
            1012: '1012 SERVICE_RESTART',
            1013: '1013 TRY_AGAIN_LATER',
            1014: '1014 CLOSE_RETAIN',
            1015: '1015 TLS_HANDSHAKE'
        }
        let error = codes[code];
        if (error === undefined) error = '0000 UNKNOWN_ERROR 未知错误';
        return error;
    },
    sendData: function (data) {
        try {
            console.info("message", data);
            this.instance.send(data);
        } catch (err) {
            console.warn("message", "创建 WebSocket 对象失败 请检查服务器地址", err);
            throw err;
        }
    },
    heartbeat: function () {
        let that = this;
        setInterval(function () {
            if (that.connected) {
                that.sendData("h");
            }
        }, 5000);
    },
}

function MessageEvent() {
    this.handlers = {};
}

MessageEvent.prototype = {
    constructor: EventTarget,
    add: function (type, handler) {
        if (typeof this.handlers[type] == 'undefined') {
            this.handlers[type] = [];
        }
        this.handlers[type].push(handler);
    },
    //触发一个事件
    fire: function (type, data,id) {
        //判断是否存在该事件类型
        if (this.handlers[type] instanceof Array) {
            let handlers = this.handlers[type];
            //在同一个事件类型下的可能存在多种处理事件，找出本次需要处理的事件
            for (let i = 0; i < handlers.length; i++) {
                //执行触发
                handlers[i](data,id);
            }
        }
    },
    fireEvent: function (event) {
        let type = event.action;
        let data = event.data;
        //判断是否存在该事件类型
        if (this.handlers[type] instanceof Array) {
            let handlers = this.handlers[type];
            //在同一个事件类型下的可能存在多种处理事件，找出本次需要处理的事件
            for (let i = 0; i < handlers.length; i++) {
                //执行触发
                handlers[i](data,event.id);
            }
        }
    },
    //注销事件
    remove: function (type, handler) {
        //判断是否存在该事件类型
        if (this.handlers[type] instanceof Array) {
            let handlers = this.handlers[type];
            //在同一个事件类型下的可能存在多种处理事件
            let index = false;
            for (let i = 0; i < handlers.length; i++) {
                //找出本次需要处理的事件下标
                if (handlers[i] === handler) {
                    index = i;
                    break;
                }
            }
            //从事件处理数组里面删除
            if (index !== false) {
                handlers.splice(index, 1);
            }
        }
    },
};